#ifdef _WIN32
#include <windows.h>
#include <winbase.h>
#include <stdlib.h>
#include <direct.h>
#else
#include <stddef.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#endif

#include "dir.h"
#include <iostream>
#include <errno.h>

bool DirUtil::CreateDir(const char *name)
{
#ifdef _WIN32
	int ret = mkdir(name);
#else
	// RWX for owner/group, and RX for others
	int ret = mkdir(name, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
#endif
	if(ret != 0 && errno != EEXIST)
	{
		fprintf(stderr, "ERROR: cannot create directory: fim\n");
		return false;
	}
	return true;
}

void DirUtil::RemoveExtension(char *out,char *str)
{
	strcpy(out,str);
	int i=strlen(out);
	while (out[i]!='.') i--;
	out[i]='\0';
}


#ifndef _WIN32
// see linuxquestions for this function
int patiMatch (const char* pattern, const char* string)
{
	switch (pattern[0])
	{
		case '\0':
			return !string[0];
		
		case '*' :
			return patiMatch(pattern+1, string) || string[0] && patiMatch(pattern, string+1);
		
		case '?' :
			return string[0] && patiMatch(pattern+1, string+1);
		
		default :
			return (toupper(pattern[0]) == toupper(string[0])) && patiMatch(pattern+1, string+1);
	}
}

bool getNextFile(DIR **dp, dirent **ep, char *pattern)
{
	while(*ep = readdir(*dp)) {
		if(patiMatch(pattern, (*ep)->d_name)) return true;
	}
	return false;
}

#endif

void DirectoryListing::First(char *result,const char *type)
{
#ifdef _WIN32
	WIN32_FIND_DATA FindFileData;

	h1=FindFirstFile(type,&FindFileData);

	if (h1!=INVALID_HANDLE_VALUE) 	
		strcpy(result,FindFileData.cFileName);	
	else strcpy(result,"");
#else
	if(dp) {
		closedir(dp);
	}
	
	if(pattern) delete[] pattern;
	pattern = new char[strlen(type) + 1];
	
	strcpy(pattern, type);
		
	dp = opendir("./");
	if( dp != NULL )
	{
		if(!getNextFile(&dp, &ep, pattern)) {
			closedir(dp); 
			dp = NULL;
			result[0] = '\0';
			return;
		}
		
		if(strlen(ep->d_name) > 0) {
			strcpy(result, ep->d_name);
		}
		else result[0] = '\0';
	}
	
#endif
}


bool DirectoryListing::Next(char *result)
{
#ifdef _WIN32
	WIN32_FIND_DATA FindFileData;
	
	if (!FindNextFile(h1,&FindFileData)) 
	{	
		FindClose(h1);
		h1 = NULL;
		return false;		
	}

	strcpy(result,FindFileData.cFileName);	

	return true;
#else
	if( dp != NULL )
	{
		if(!getNextFile(&dp, &ep, pattern)) {
			closedir(dp);
			dp = NULL;
			return false;
		}
		strcpy(result, ep->d_name);
		return true;
	}
	return false;
#endif
}


